﻿namespace JoinBox.Basal;


using System.Collections;
using System.Net.NetworkInformation;


public static class PortTool
{
    // https://blog.csdn.net/ljz9425/article/details/7684813
    // https://blog.csdn.net/qq_41217121/article/details/80385965
    /// <summary>
    /// 获取第一个可用的端口号
    /// </summary>
    /// <returns></returns>
    public static int GetFirstAvailablePort()
    {
        int MAX_PORT = 65535;  // 系统tcp/udp端口数最大是65535
        int BEGIN_PORT = 10000;// 从这个端口开始检测
        for (int i = BEGIN_PORT; i < MAX_PORT; i++)
            if (PortIsAvailable(i))
                return i;// 可用
        return -1;
    }
    /// <summary>
    /// 端口是否可用
    /// </summary>
    /// <param name="port"></param>
    /// <returns>未用true,已用false</returns>
    public static bool PortIsAvailable(int port)
    {
        var portUsed = PortIsUsed();
        foreach (int p in portUsed)
            if (p == port)
                return false;
        return true;
    }
    /// <summary>
    /// 获取操作系统已用的端口号
    /// </summary>
    /// <returns></returns>
    static IList PortIsUsed()
    {
        // 获取本地计算机的网络连接和通信统计数据的信息
        var ipGlobalProperties = IPGlobalProperties.GetIPGlobalProperties();
        // 返回本地计算机上的所有Tcp监听程序
        var ipsTCP = ipGlobalProperties.GetActiveTcpListeners();
        // 返回本地计算机上的所有UDP监听程序
        var ipsUDP = ipGlobalProperties.GetActiveUdpListeners();
        // 返回本地计算机上的Internet协议版本4(IPV4 传输控制协议(TCP)连接的信息。
        var tcpConnInfoArray = ipGlobalProperties.GetActiveTcpConnections();
        IList allPorts = new ArrayList();
        foreach (var ep in ipsTCP)
            allPorts.Add(ep.Port);
        foreach (var ep in ipsUDP)
            allPorts.Add(ep.Port);
        foreach (var conn in tcpConnInfoArray)
            allPorts.Add(conn.LocalEndPoint.Port);
        return allPorts;
    }

}
